package org.nicta.colt.utils;


import cern.colt.matrix.DoubleFactory1D;
import cern.colt.matrix.DoubleMatrix1D;
import cern.colt.matrix.DoubleMatrix2D;
import cern.jet.math.Functions;
import cern.jet.math.Mult;

public class ColtUtils {

	
	public static double[] flatten2DMatrixToArray(DoubleMatrix2D m){
		return flattenTo1D(m).toArray();
	}

	public static DoubleMatrix1D flattenTo1D(DoubleMatrix2D m){
		int rows,columns;
		int index = 0;
		rows = m.rows();
		columns = m.columns();
		DoubleMatrix1D result = DoubleFactory1D.dense.make(rows*columns);
		for(int i=0; i < rows; i++){
			for(int j = 0; j < columns; j++){
				result.set(index, m.get(i, j));
				index++;
			}
		}
		return result;
	}
	
	public static void flattenTo1D(DoubleMatrix2D m, double[] flat){
		int rows,columns;
		int index = 0;
		rows = m.rows();
		columns = m.columns();
		DoubleMatrix1D result = DoubleFactory1D.dense.make(rows*columns);
		for(int i=0; i < rows; i++){
			for(int j = 0; j < columns; j++){
				flat[index]=  m.get(i, j);
				index++;
			}
		}
	}
	public static void mergeFlattenTo1D(DoubleMatrix2D m,DoubleMatrix2D n,double[] flat){
		int rowsM,columnsM, rowsN, columnsN;
		int index = 0;
		rowsM = m.rows();
		columnsM = m.columns();
		rowsN = n.rows();
		columnsN = n.columns();
		DoubleMatrix1D result = DoubleFactory1D.dense.make(rowsN*columnsN+rowsM*columnsM);
		for(int i= 0; i < rowsM; i++){
			for(int j = 0; j < columnsM; j++){
				flat[index]=  m.get(i, j);
				index++;
			}
		}
		for(int i=0; i < rowsN; i++){
			for(int j = 0; j < columnsN; j++){
				flat[index]=  n.get(i, j);
				index++;
			}
		}
		
	}
	public static DoubleMatrix2D multScalar(DoubleMatrix2D x, double alpha){
		DoubleMatrix2D mat = x.copy();
		mat.assign(Mult.mult(alpha));
		return mat;

	}
	
	public static DoubleMatrix1D multScalar(DoubleMatrix1D x, double alpha){
		DoubleMatrix1D mat = x.copy();
		mat.assign(Mult.mult(alpha));
		return mat;

	}

	public static void assignByUnflattening(double[] flat,
			DoubleMatrix2D m,
			DoubleMatrix2D n) {
		int rowsM,columnsM, rowsN, columnsN;
		int index = 0;
		rowsM = m.rows();
		columnsM = m.columns();
		rowsN = n.rows();
		columnsN = n.columns();
		for(int i=0; i < rowsM; i++){
			for(int j = 0; j < columnsM; j++){
				m.set(i, j,flat[index]);
				index++;
			}
		}
		for(int i=0; i < rowsN; i++){
			for(int j = 0; j < columnsN; j++){
				n.set(i, j, flat[index]);
				index++;
			}
		}
		
	}
	
	public static void sumRowByVector(DoubleMatrix2D m, DoubleMatrix1D v, int row){
		m.viewRow(row).assign(v,Functions.plus);
	}
	
	public static void sumColumnByVector(DoubleMatrix2D m, DoubleMatrix1D v, int row){
		m.viewColumn(row).assign(v,Functions.plus);
	}
	
	public static void assignRows(DoubleMatrix2D m, DoubleMatrix1D v, int row){
		m.viewRow(row).assign(v);
	}
	public static void assignColumns(DoubleMatrix2D m, DoubleMatrix1D v, 
			int column){
		m.viewColumn(column).assign(v);
	}
}
